home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / 92052tar.gz / 920528.tar / transport.c < prev    next >
C/C++ Source or Header  |  1991-12-05  |  10KB  |  359 lines

  1. /* @(#) $Header: transport.c,v 1.10 91/12/04 18:26:00 deyke Exp $ */
  2.  
  3. #include <stdlib.h>
  4. #include <string.h>
  5.  
  6. #include "global.h"
  7. #include "netuser.h"
  8. #include "mbuf.h"
  9. #include "timer.h"
  10. #include "ax25.h"
  11. #include "lapb.h"
  12. #include "netrom.h"
  13. #include "tcp.h"
  14. #include "session.h"
  15. #include "transport.h"
  16.  
  17. static int convert_eol __ARGS((struct mbuf **bpp, int mode, int *last_chr));
  18. static void transport_recv_upcall_ax25 __ARGS((struct ax25_cb *cp, int cnt));
  19. static void transport_recv_upcall_netrom __ARGS((struct circuit *cp, int cnt));
  20. static void transport_recv_upcall_tcp __ARGS((struct tcb *cp, int cnt));
  21. static void transport_send_upcall_ax25 __ARGS((struct ax25_cb *cp, int cnt));
  22. static void transport_send_upcall_netrom __ARGS((struct circuit *cp, int cnt));
  23. static void transport_send_upcall_tcp __ARGS((struct tcb *cp, int cnt));
  24. static void transport_state_upcall_ax25 __ARGS((struct ax25_cb *cp, int oldstate, int newstate));
  25. static void transport_state_upcall_netrom __ARGS((struct circuit *cp, int oldstate, int newstate));
  26. static void transport_state_upcall_tcp __ARGS((struct tcb *cp, int oldstate, int newstate));
  27. static struct ax25_cb *transport_open_ax25 __ARGS((char *address, struct transport_cb *tp));
  28. static struct circuit *transport_open_netrom __ARGS((char *address, struct transport_cb *tp));
  29. static struct tcb *transport_open_tcp __ARGS((char *address, struct transport_cb *tp));
  30.  
  31. /*---------------------------------------------------------------------------*/
  32.  
  33. static int  convert_eol(bpp, mode, last_chr)
  34. struct mbuf **bpp;
  35. int  mode, *last_chr;
  36. {
  37.  
  38.   char  buf[10240], *p;
  39.   int  chr, cnt;
  40.   struct mbuf *bp;
  41.  
  42.   p = buf;
  43.   bp = *bpp;
  44.   while (bp) {
  45.     for (; bp->cnt; bp->cnt--) {
  46.       switch (chr = *bp->data++) {
  47.       case '\0':
  48.     break;
  49.       case '\n':
  50.     if (*last_chr == '\r')
  51.       break;
  52.       case '\r':
  53.     switch (mode) {
  54.     case EOL_CR:
  55.       *p++ = '\r';
  56.       break;
  57.     case EOL_LF:
  58.       *p++ = '\n';
  59.       break;
  60.     case EOL_CRLF:
  61.       *p++ = '\r';
  62.       *p++ = '\n';
  63.       break;
  64.     }
  65.     break;
  66.       default:
  67.     *p++ = chr;
  68.     break;
  69.       }
  70.       *last_chr = chr;
  71.     }
  72.     bp = free_mbuf(bp);
  73.   }
  74.   cnt = p - buf;
  75.   *bpp = qdata(buf, cnt);
  76.   return cnt;
  77. }
  78.  
  79. /*---------------------------------------------------------------------------*/
  80.  
  81. static void transport_recv_upcall_ax25(cp, cnt)
  82. struct ax25_cb *cp;
  83. int cnt;
  84. {
  85.   struct transport_cb *tp = (struct transport_cb *) cp->user;
  86.   if (tp->r_upcall) (*tp->r_upcall)(tp, cnt);
  87. }
  88.  
  89. /*---------------------------------------------------------------------------*/
  90.  
  91. static void transport_recv_upcall_netrom(cp, cnt)
  92. struct circuit *cp;
  93. int cnt;
  94. {
  95.   struct transport_cb *tp = (struct transport_cb *) cp->user;
  96.   if (tp->r_upcall) (*tp->r_upcall)(tp, cnt);
  97. }
  98.  
  99. /*---------------------------------------------------------------------------*/
  100.  
  101. static void transport_recv_upcall_tcp(cp, cnt)
  102. struct tcb *cp;
  103. int cnt;
  104. {
  105.   struct transport_cb *tp = (struct transport_cb *) cp->user;
  106.   if (tp->r_upcall) (*tp->r_upcall)(tp, cnt);
  107. }
  108.  
  109. /*---------------------------------------------------------------------------*/
  110.  
  111. static void transport_send_upcall_ax25(cp, cnt)
  112. struct ax25_cb *cp;
  113. int cnt;
  114. {
  115.   struct transport_cb *tp = (struct transport_cb *) cp->user;
  116.   if (tp->t_upcall) (*tp->t_upcall)(tp, cnt);
  117. }
  118.  
  119. /*---------------------------------------------------------------------------*/
  120.  
  121. static void transport_send_upcall_netrom(cp, cnt)
  122. struct circuit *cp;
  123. int cnt;
  124. {
  125.   struct transport_cb *tp = (struct transport_cb *) cp->user;
  126.   if (tp->t_upcall) (*tp->t_upcall)(tp, cnt);
  127. }
  128.  
  129. /*---------------------------------------------------------------------------*/
  130.  
  131. static void transport_send_upcall_tcp(cp, cnt)
  132. struct tcb *cp;
  133. int cnt;
  134. {
  135.   struct transport_cb *tp = (struct transport_cb *) cp->user;
  136.   if (tp->t_upcall) (*tp->t_upcall)(tp, cnt);
  137. }
  138.  
  139. /*---------------------------------------------------------------------------*/
  140.  
  141. static void transport_state_upcall_ax25(cp, oldstate, newstate)
  142. struct ax25_cb *cp;
  143. int  oldstate, newstate;
  144. {
  145.   struct transport_cb *tp = (struct transport_cb *) cp->user;
  146.   if (tp->s_upcall && newstate == DISCONNECTED) (*tp->s_upcall)(tp);
  147. }
  148.  
  149. /*---------------------------------------------------------------------------*/
  150.  
  151. static void transport_state_upcall_netrom(cp, oldstate, newstate)
  152. struct circuit *cp;
  153. int  oldstate, newstate;
  154. {
  155.   struct transport_cb *tp = (struct transport_cb *) cp->user;
  156.   if (tp->s_upcall && newstate == DISCONNECTED) (*tp->s_upcall)(tp);
  157. }
  158.  
  159. /*---------------------------------------------------------------------------*/
  160.  
  161. static void transport_state_upcall_tcp(cp, oldstate, newstate)
  162. struct tcb *cp;
  163. int oldstate, newstate;
  164. {
  165.   struct transport_cb *tp = (struct transport_cb *) cp->user;
  166.   switch (newstate) {
  167.   case TCP_CLOSE_WAIT:
  168.     close_tcp(cp);
  169.     break;
  170.   case TCP_CLOSED:
  171.     if (tp->s_upcall) (*tp->s_upcall)(tp);
  172.     break;
  173.   }
  174. }
  175.  
  176. /*---------------------------------------------------------------------------*/
  177.  
  178. static struct ax25_cb *transport_open_ax25(address, tp)
  179. char  *address;
  180. struct transport_cb *tp;
  181. {
  182.  
  183.   char  *pathptr;
  184.   char  *strptr;
  185.   char  path[10*AXALEN];
  186.   char  tmp[1024];
  187.  
  188.   pathptr = path;
  189.   strptr = strtok(strcpy(tmp, address), " \t\r\n");
  190.   while (strptr) {
  191.     if (strncmp("via", strptr, strlen(strptr))) {
  192.       if (pathptr > path + 10 * AXALEN - 1) return 0;
  193.       if (setcall(pathptr, strptr)) return 0;
  194.       if (pathptr == path) {
  195.     pathptr += AXALEN;
  196.     addrcp(pathptr, Mycall);
  197.       }
  198.       pathptr += AXALEN;
  199.     }
  200.     strptr = strtok(NULLCHAR, " \t\r\n");
  201.   }
  202.   if (pathptr < path + 2 * AXALEN) return 0;
  203.   pathptr[-1] |= E;
  204.   tp->recv = (int (*)()) recv_ax;
  205.   tp->send = (int (*)()) send_ax;
  206.   tp->send_space = (int (*)()) space_ax;
  207.   tp->close = (int (*)()) close_ax;
  208.   tp->del = (int (*)()) del_ax;
  209.   return open_ax(path, AX_ACTIVE, transport_recv_upcall_ax25, transport_send_upcall_ax25, transport_state_upcall_ax25, (char *) tp);
  210. }
  211.  
  212. /*---------------------------------------------------------------------------*/
  213.  
  214. static struct circuit *transport_open_netrom(address, tp)
  215. char *address;
  216. struct transport_cb *tp;
  217. {
  218.  
  219.   char *ascii_node, *ascii_user;
  220.   char node[AXALEN], user[AXALEN];
  221.   char tmp[1024];
  222.  
  223.   strcpy(tmp, address);
  224.   if (!(ascii_node = strtok(tmp, " \t\r\n")) ||
  225.       setcall(node, ascii_node))
  226.     return 0;
  227.   if (!(ascii_user = strtok(NULLCHAR, " \t\r\n")) ||
  228.       setcall(user, ascii_user))
  229.     addrcp(user, Mycall);
  230.   tp->recv = (int (*)()) recv_nr;
  231.   tp->send = (int (*)()) send_nr;
  232.   tp->send_space = (int (*)()) space_nr;
  233.   tp->close = (int (*)()) close_nr;
  234.   tp->del = (int (*)()) del_nr;
  235.   return open_nr(node, user, 0, transport_recv_upcall_netrom, transport_send_upcall_netrom, transport_state_upcall_netrom, (char *) tp);
  236. }
  237.  
  238. /*---------------------------------------------------------------------------*/
  239.  
  240. static struct tcb *transport_open_tcp(address, tp)
  241. char  *address;
  242. struct transport_cb *tp;
  243. {
  244.  
  245.   char  *host, *port, tmp[1024];
  246.   struct socket fsocket, lsocket;
  247.  
  248.   if (!(host = strtok(strcpy(tmp, address), " \t\r\n"))) return 0;
  249.   if (!(port = strtok(NULLCHAR, " \t\r\n"))) return 0;
  250.   if (!(fsocket.address = resolve(host))) return 0;
  251.   if (!(fsocket.port = tcp_port_number(port))) return 0;
  252.   lsocket.address = INADDR_ANY;
  253.   lsocket.port = Lport++;
  254.   tp->recv = (int (*)()) recv_tcp;
  255.   tp->send = (int (*)()) send_tcp;
  256.   tp->send_space = (int (*)()) space_tcp;
  257.   tp->close = (int (*)()) close_tcp;
  258.   tp->del = (int (*)()) del_tcp;
  259.   return open_tcp(&lsocket, &fsocket, TCP_ACTIVE, 0, transport_recv_upcall_tcp, transport_send_upcall_tcp, transport_state_upcall_tcp, 0, (int) tp);
  260. }
  261.  
  262. /*---------------------------------------------------------------------------*/
  263.  
  264. struct transport_cb *transport_open(protocol, address, r_upcall, t_upcall, s_upcall, user)
  265. char *protocol;
  266. char *address;
  267. void (*r_upcall) __ARGS((struct transport_cb *tp, int cnt));
  268. void (*t_upcall) __ARGS((struct transport_cb *tp, int cnt));
  269. void (*s_upcall) __ARGS((struct transport_cb *tp));
  270. void *user;
  271. {
  272.   struct transport_cb *tp;
  273.  
  274.   tp = calloc(1, sizeof(struct transport_cb ));
  275.   tp->r_upcall = r_upcall;
  276.   tp->t_upcall = t_upcall;
  277.   tp->s_upcall = s_upcall;
  278.   tp->user = user;
  279.   tp->timer.func = (void (*)()) transport_close;
  280.   tp->timer.arg = tp;
  281.   Net_error = INVALID;
  282.   if (!strcmp(protocol, "ax25"))
  283.     tp->cp = transport_open_ax25(address, tp);
  284.   else if (!strcmp(protocol, "netrom"))
  285.     tp->cp = transport_open_netrom(address, tp);
  286.   else if (!strcmp(protocol, "tcp"))
  287.     tp->cp = transport_open_tcp(address, tp);
  288.   else
  289.     Net_error = NOPROTO;
  290.   if (tp->cp) return tp;
  291.   free(tp);
  292.   return 0;
  293. }
  294.  
  295. /*---------------------------------------------------------------------------*/
  296.  
  297. int  transport_recv(tp, bpp, cnt)
  298. struct transport_cb *tp;
  299. struct mbuf **bpp;
  300. int cnt;
  301. {
  302.   int  result;
  303.  
  304.   if dur_timer(&tp->timer) start_timer(&tp->timer);
  305.   result = (*tp->recv)(tp->cp, bpp, cnt);
  306.   if (result < 1 || tp->recv_mode == EOL_NONE) return result;
  307.   return convert_eol(bpp, tp->recv_mode, &tp->recv_char);
  308. }
  309.  
  310. /*---------------------------------------------------------------------------*/
  311.  
  312. int  transport_send(tp, bp)
  313. struct transport_cb *tp;
  314. struct mbuf *bp;
  315. {
  316.   if dur_timer(&tp->timer) start_timer(&tp->timer);
  317.   if (tp->send_mode != EOL_NONE)
  318.     convert_eol(&bp, tp->send_mode, &tp->send_char);
  319.   return (*tp->send)(tp->cp, bp);
  320. }
  321.  
  322. /*---------------------------------------------------------------------------*/
  323.  
  324. int  transport_send_space(tp)
  325. struct transport_cb *tp;
  326. {
  327.   return (*tp->send_space)(tp->cp);
  328. }
  329.  
  330. /*---------------------------------------------------------------------------*/
  331.  
  332. void transport_set_timeout(tp, timeout)
  333. struct transport_cb *tp;
  334. int  timeout;
  335. {
  336.   set_timer(&tp->timer, timeout * 1000L);
  337.   start_timer(&tp->timer);
  338. }
  339.  
  340. /*---------------------------------------------------------------------------*/
  341.  
  342. int  transport_close(tp)
  343. struct transport_cb *tp;
  344. {
  345.   return (*tp->close)(tp->cp);
  346. }
  347.  
  348. /*---------------------------------------------------------------------------*/
  349.  
  350. int  transport_del(tp)
  351. struct transport_cb *tp;
  352. {
  353.   (*tp->del)(tp->cp);
  354.   stop_timer(&tp->timer);
  355.   free(tp);
  356.   return 0;
  357. }
  358.  
  359.